#ifndef ESP_TASK_EXECUTOR_H
#define ESP_TASK_EXECUTOR_H

#include <functional>
#include <chrono>
#include <string>
#include <atomic>
#include <queue>
#include <condition_variable>
#include <mutex>
#include <list>


#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/event_groups.h>
#include <freertos/semphr.h>

// 任务优先级定义
enum class TaskPriority : uint8_t {
  TASKLOW = 1,
  TASKNORMAL = 2,
  TASKHIGH = 3,
  TASKCRITICAL = 4
};

// 任务类型定义
enum class TaskType : uint8_t {
  IMMEDIATE,      // 立即执行
  SCHEDULED,      // 定时执行
  PERIODIC,       // 周期性执行
  DELAYED         // 延迟执行
};

// 任务状态
enum class TaskStatus : uint8_t {
  PENDING,        // 等待执行
  RUNNING,        // 正在执行
  COMPLETED,      // 已完成
  CANCELLED,      // 已取消
  FAILED          // 执行失败
};

// 任务句柄
using TaskId = uint32_t;


// 任务包装器 - 封装任务的所有相关属性和状态
struct Task {
  TaskId id;                                        // 任务的唯一标识符
  std::function<void()> callback;                   // 任务的执行函数
  TaskType type;                                    // 任务类型（立即执行、延迟执行、周期性等）
  TaskPriority priority;                            // 任务优先级
  TaskStatus status;                                // 任务当前状态（等待中、执行中、已完成等）
  std::chrono::steady_clock::time_point schedule_time; // 任务计划执行时间点
  std::chrono::milliseconds interval;               // 周期性任务的执行间隔时间
  uint32_t retry_count;                             // 当前重试次数
  uint32_t max_retries;                             // 最大允许重试次数
  std::string name;                                 // 任务名称
  
  /**
   * @brief 任务构造函数
   * @param task_id 任务ID
   * @param cb 任务回调函数
   * @param t 任务类型，默认为立即执行
   * @param prio 任务优先级，默认为普通优先级
   * @param task_name 任务名称，默认为空字符串
   */
  Task(TaskId task_id, std::function<void()> cb, TaskType t = TaskType::IMMEDIATE, TaskPriority prio = TaskPriority::TASKNORMAL, const std::string& task_name = "")
      : id(task_id), callback(std::move(cb)), type(t), priority(prio), status(TaskStatus::PENDING), retry_count(0), max_retries(0), name(task_name) {
      schedule_time = std::chrono::steady_clock::now();  // 设置任务计划执行时间为当前时间
      interval = std::chrono::milliseconds(0);          // 初始化任务执行间隔为0
  }
};


/**
 * @brief 任务执行器类，负责管理和执行任务
 */
class TaskExecutor {
  public:
    /**
     * @brief 构造函数
     * @param name 执行器名称
     * @param stack_size 任务栈大小，默认4096字节
     * @param priority FreeRTOS任务优先级，默认2
     * @param core_id 运行的CPU核心ID，默认不指定具体核心
     */
    TaskExecutor(const std::string& name, uint32_t stack_size = 4096, 
                  UBaseType_t priority = 2, BaseType_t core_id = tskNO_AFFINITY);


    //析构函数
    ~TaskExecutor();

    //禁用拷贝构造和赋值操作
    TaskExecutor(const TaskExecutor&) = delete;
    TaskExecutor& operator=(const TaskExecutor&) = delete;


    // 等待所有任务完成
    void WaitForCompletion();

    /**
     * @brief 添加新任务到执行器
     * @param callback 任务回调函数
     * @param type 任务类型，默认为立即执行
     * @param priority 任务优先级，默认为普通优先级
     * @param name 任务名称，默认为空
     * @return 返回任务ID
     */
    TaskId AddTask(std::function<void()> callback, 
                    TaskType type = TaskType::IMMEDIATE,
                    TaskPriority priority = TaskPriority::TASKNORMAL,
                    const std::string& name = "");
    // 添加延迟任务
    TaskId AddDelayedTask(std::function<void()> callback, 
                          std::chrono::milliseconds delay,
                          TaskPriority priority = TaskPriority::TASKNORMAL,
                          const std::string& name = "");

    // 添加周期性任务
    TaskId AddPeriodicTask( std::function<void()> callback, 
                            std::chrono::milliseconds interval,
                            TaskPriority priority = TaskPriority::TASKNORMAL,
                            const std::string& name = "");

    // 删除任务
    /**
     * @brief 通过任务ID删除任务
     * @param task_id 要删除的任务ID
     * @return 成功删除返回true，否则返回false
     */
    bool RemoveTask(TaskId task_id);

    /**
     * @brief 通过任务名称删除任务（删除第一个匹配的任务）
     * @param name 要删除的任务名称
     * @return 成功删除返回true，否则返回false
     */
    bool RemoveTask(const std::string& name);

    /**
     * @brief 通过任务名称删除所有匹配的任务
     * @param name 要删除的任务名称
     * @return 删除的任务数量
     */
    uint32_t RemoveAllTasksByName(const std::string& name);

  private:
    // 配置
    static constexpr uint32_t MAX_QUEUE_SIZE = 2000;
    
    std::string name_;  
    TaskHandle_t task_handle_;


    // 任务队列 - 使用优先级队列
    struct TaskComparator {
        bool operator()(const std::shared_ptr<Task>& a, const std::shared_ptr<Task>& b) const {
            if (a->priority != b->priority) {
                return static_cast<uint8_t>(a->priority) < static_cast<uint8_t>(b->priority);
            }
            return a->schedule_time > b->schedule_time;
        }
    };
    std::priority_queue<std::shared_ptr<Task>, std::vector<std::shared_ptr<Task>>, TaskComparator> task_queue_;
    
    mutable std::mutex queue_mutex_;
    std::condition_variable condition_;
    
    // 任务管理
    std::atomic<TaskId> next_task_id_{1};
    std::atomic<bool> paused_{false};
    // 统计信息
    mutable std::atomic<uint32_t> pending_tasks_{0};
    /**
     * @brief 执行器主循环，实际执行任务
     */
    void ExecutorLoop();
    /**
     * @brief 执行单个任务
     * @param task 要执行的任务
     */
    void ProcessTasks();
    void ExecuteTask(std::shared_ptr<Task> task);
    void ReschedulePeriodicTask(std::shared_ptr<Task> task);
  };
  

#endif // !ESP_TASK_EXECUTOR_H